home *** CD-ROM | disk | FTP | other *** search
- .286
- page 58, 132
- name FSPXW
- title FSPXW (Flightstick Pro driver for XWING).
- subttl Copyright (C) 1994 Randall Hyde.
-
-
- ; FSPXW.EXE
- ;
- ; Usage:
- ; FSPXW
- ;
- ; This program executes the XWING.EXE program and patches it to use the
- ; Flightstick Pro.
-
-
- byp textequ <byte ptr>
- wp textequ <word ptr>
-
-
- cseg segment para public 'CODE'
- cseg ends
-
- sseg segment para stack 'STACK'
- sseg ends
-
- zzzzzzseg segment para public 'zzzzzzseg'
- zzzzzzseg ends
-
- include stdlib.a
- includelib stdlib.lib
- matchfuncs
-
- ifndef debug
- Installation segment para public 'Install'
- Installation ends
- endif
-
- CSEG segment para public 'CODE'
- assume cs:cseg, ds:nothing
-
- ; Timer interrupt vector
-
- Int1CVect dd ?
-
-
- ; PSP- Program Segment Prefix. Needed to free up memory before running
- ; the real application program.
-
- PSP dw 0
-
-
-
- ; Program Loading data structures (for DOS).
-
- ExecStruct dw 0 ;Use parent's Environment blk.
- dd CmdLine ;For the cmd ln parms.
- dd DfltFCB
- dd DfltFCB
- LoadSSSP dd ?
- LoadCSIP dd ?
- PgmName dd Pgm
-
-
- ; Variables for the throttle pot.
- ; LastThrottle contains the character last sent (so we only send one copy).
- ; ThrtlCntDn counts the number of times the throttle routine gets called.
-
- LastThrottle db 0
- ThrtlCntDn db 10
-
-
- ; Button Mask- Used to mask out the programmed buttons when the game
- ; reads the real buttons.
-
- ButtonMask db 0f0h
-
-
- ; The following variables allow the user to reprogram the buttons.
-
- KeyRdf struct
- Ptrs dw ?
- ptr2 dw ?
- ptr3 dw ?
- ptr4 dw ?
- Index dw ?
- Cnt dw ?
- Pgmd dw ?
- KeyRdf ends
-
-
- ; Left codes are output if the cooley switch is pressed to the left.
-
- Left KeyRdf <Left1, Left2, Left3, Left4, 0, 6, 1>
- Left1 dw '7', 0,0,0,0,0,0,0,0
- Left2 dw '4', 0,0,0,0,0,0,0,0
- Left3 dw '1', 0,0,0,0,0,0,0,0
- Left4 dw 0, 0,0,0,0,0,0,0,0
-
- ; Right codes are output if the cooley switch is pressed to the Right.
-
- Right KeyRdf <Right1, Right2, Right3, Right4, 0, 6, 1>
- Right1 dw '9', 0,0,0,0,0,0,0,0
- Right2 dw '6', 0,0,0,0,0,0,0,0
- Right3 dw '3', 0,0,0,0,0,0,0,0
- Right4 dw 0, 0,0,0,0,0,0,0,0
-
- ; Up codes are output if the cooley switch is pressed Up.
-
- Up KeyRdf <Up1, Up2, Up3, Up4, 0, 2, 1>
- Up1 dw '8', 0,0,0,0,0,0,0,0
- Up2 dw 0, 0,0,0,0,0,0,0,0
- Up3 dw 0, 0,0,0,0,0,0,0,0
- Up4 dw 0, 0,0,0,0,0,0,0,0
-
- ; DownKey codes are output if the cooley switch is pressed Down.
-
- Down KeyRdf <Down1, Down2, Down3, Down4, 0, 2, 1>
- Down1 dw '2', 0,0,0,0,0,0,0,0
- Down2 dw 0, 0,0,0,0,0,0,0,0
- Down3 dw 0, 0,0,0,0,0,0,0,0
- Down4 dw 0, 0,0,0,0,0,0,0,0
-
- ; Sw0 codes are output if the user pulls the trigger.
-
- Sw0 KeyRdf <Sw01, Sw02, Sw03, Sw04, 0, 0, 0>
- Sw01 dw 0, 0,0,0,0,0,0,0,0
- Sw02 dw 0, 0,0,0,0,0,0,0,0
- Sw03 dw 0, 0,0,0,0,0,0,0,0
- Sw04 dw 0, 0,0,0,0,0,0,0,0
-
-
- ; Sw1 codes are output if the user presses Sw1 (the left button
- ; if the user hasn't swapped the left and right buttons).
-
- Sw1 KeyRdf <Sw11, Sw12, Sw13, Sw14, 0, 0, 0>
- Sw11 dw 0, 0,0,0,0,0,0,0,0
- Sw12 dw 0, 0,0,0,0,0,0,0,0
- Sw13 dw 0, 0,0,0,0,0,0,0,0
- Sw14 dw 0, 0,0,0,0,0,0,0,0
-
- ; Sw2 codes are output if the user presses Sw2 (the middle button).
-
- Sw2 KeyRdf <Sw21, Sw22, Sw23, Sw24, 0, 2, 1>
- Sw21 dw 'w', 0,0,0,0,0,0,0,0
- Sw22 dw 0, 0,0,0,0,0,0,0,0
- Sw23 dw 0, 0,0,0,0,0,0,0,0
- Sw24 dw 0, 0,0,0,0,0,0,0,0
-
- ; Sw3 codes are output if the user presses Sw3 (the right button
- ; if the user hasn't swapped the left and right buttons).
-
- Sw3 KeyRdf <Sw31, Sw32, Sw33, Sw34, 0, 0, 0>
- Sw31 dw 0, 0,0,0,0,0,0,0,0
- Sw32 dw 0, 0,0,0,0,0,0,0,0
- Sw33 dw 0, 0,0,0,0,0,0,0,0
- Sw34 dw 0, 0,0,0,0,0,0,0,0
-
- ; Switch status buttons:
-
- CurSw db 0
- LastSw db 0
-
-
- ;****************************************************************************
- ; FSPXW patch begins here. This is the memory resident part. Only put code
- ; which which has to be present at run-time or needs to be resident after
- ; freeing up memory.
- ;****************************************************************************
-
- Main proc
- mov cs:PSP, ds
- mov ax, cseg ;Get ptr to vars segment
- mov ds, ax
-
-
- ; Get the current INT 1Ch interrupt vector:
-
- mov ax, 351ch
- int 21h
- mov wp Int1CVect, bx
- mov wp Int1CVect+2, es
-
- ; The following call to MEMINIT assumes no error occurs. If it does,
- ; we're hosed anyway.
-
- mov ax, zzzzzzseg
- mov es, ax
- mov cx, 1024/16
- meminit2
-
-
- ; Do some initialization before running the game. These are calls to the
- ; initialization code which gets dumped before actually running XWING.
-
- call far ptr ChkBIOS15
- call far ptr Identify
- ; call far ptr Reprogram
- call far ptr Calibrate
-
- ; If any switches were programmed, remove those switches from the
- ; ButtonMask:
-
- mov al, 0f0h ;Assume all buttons are okay.
- cmp sw0.pgmd, 0
- je Sw0NotPgmd
- and al, 0e0h ;Remove sw0 from contention.
- Sw0NotPgmd:
-
- cmp sw1.pgmd, 0
- je Sw1NotPgmd
- and al, 0d0h ;Remove Sw1 from contention.
- Sw1NotPgmd:
-
- cmp sw2.pgmd, 0
- je Sw2NotPgmd
- and al, 0b0h ;Remove Sw2 from contention.
- Sw2NotPgmd:
-
- cmp sw3.pgmd, 0
- je Sw3NotPgmd
- and al, 070h ;Remove Sw3 from contention.
- Sw3NotPgmd:
- mov ButtonMask, al ;Save result as button mask
-
- ; Now, free up memory from ZZZZZZSEG on to make room for XWING.
- ; Note: Absolutely no calls to UCR Standard Library routines from
- ; this point forward! (ExitPgm is okay, it's just a macro which calls DOS.)
- ; Note that after the execution of this code, none of the code & data
- ; from zzzzzzseg on is valid.
-
- mov bx, zzzzzzseg
- sub bx, PSP
- inc bx
- mov es, PSP
- mov ah, 4ah
- int 21h
- jnc GoodRealloc
- print
- byte "Memory allocation error."
- byte cr,lf,0
- jmp Quit
-
- GoodRealloc:
-
- ; Now load the XWING program into memory:
-
- mov bx, seg ExecStruct
- mov es, bx
- mov bx, offset ExecStruct ;Ptr to program record.
- lds dx, PgmName
- mov ax, 4b01h ;Load, do not exec, pgm
- int 21h
- jc Quit ;If error loading file.
-
- ; Search for the joystick code in memory:
-
- mov si, zzzzzzseg
- mov ds, si
- xor si, si
-
- mov di, cs
- mov es, di
- mov di, offset JoyStickCode
- mov cx, JoyLength
- call FindCode
- jc Quit ;If didn't find joystick code.
-
-
- ; Patch the XWING joystick code here
-
- mov byp ds:[si], 09ah ;Far call
- mov wp ds:[si+1], offset ReadGame
- mov wp ds:[si+3], cs
-
- ; Find the Button code here.
-
- mov si, zzzzzzseg
- mov ds, si
- xor si, si
-
- mov di, cs
- mov es, di
- mov di, offset ReadSwCode
- mov cx, ButtonLength
- call FindCode
- jc Quit
-
- ; Patch the button code here.
-
- mov byp ds:[si], 9ah
- mov wp ds:[si+1], offset ReadButtons
- mov wp ds:[si+3], cs
- mov byp ds:[si+5], 90h ;NOP.
-
-
- ; Patch in our timer interrupt handler:
-
- mov ax, 251ch
- mov dx, seg MyInt1C
- mov ds, dx
- mov dx, offset MyInt1C
- int 21h
-
-
- ; Okay, start the XWING.EXE program running
-
- mov ah, 62h ;Get PSP
- int 21h
- mov ds, bx
- mov es, bx
- mov wp ds:[10], offset Quit
- mov wp ds:[12], cs
- mov ss, wp cseg:LoadSSSP+2
- mov sp, wp cseg:LoadSSSP
- jmp dword ptr cseg:LoadCSIP
-
-
- Quit: lds dx, cs:Int1CVect ;Restore timer vector.
- mov ax, 251ch
- int 21h
- ExitPgm
-
- Main endp
-
- ;****************************************************************************
- ;
- ; ReadGame- This routine gets called whenever XWing reads the joystick.
- ; On every 10th call it will read the throttle pot and send
- ; appropriate characters to the type ahead buffer, if
- ; necessary.
-
- assume ds:nothing
- ReadGame proc far
- dec cs:ThrtlCntDn ;Only do this each 10th time
- jne SkipThrottle ; XWING calls the joystick
- mov cs:ThrtlCntDn, 10 ; routine.
-
- push ax
- push bx ;No need to save bp, dx, or cx as
- push di ; XWING preserves these.
-
- mov ah, 84h
- mov dx, 103h ;Read the throttle pot
- int 15h
-
- ; Convert the value returned by the pot routine into the four characters
- ; 0..63:"\", 64..127:"[", 128..191:"]", 192..255:<bs>, to denote zero, 1/3,
- ; 2/3, and full power, respectively.
-
- mov dl, al
- mov ax, "\" ;Zero power
- cmp dl, 192
- jae SetPower
- mov ax, "[" ;1/3 power.
- cmp dl, 128
- jae SetPower
- mov ax, "]" ;2/3 power.
- cmp dl, 64
- jae SetPower
- mov ax, 8 ;BS, full power.
- SetPower: cmp al, cs:LastThrottle
- je SkipPIB
- mov cs:LastThrottle, al
- call PutInBuffer
-
- SkipPIB: pop di
- pop bx
- pop ax
- SkipThrottle: neg bx ;XWING returns data in these registers.
- neg di ;We patched the NEG and STI instrs
- sti ; so do that here.
- ret
- ReadGame endp
-
- assume ds:nothing
- ReadButtons proc far
- mov ah, 84h
- mov dx, 0
- int 15h
- not al
- and al, ButtonMask ;Turn off pgmd buttons.
- ret
- ReadButtons endp
-
-
-
- ; MyInt1C- Called every 1/18th second. Reads switches and decides if it
- ; should shove some characters into the type ahead buffer.
-
- assume ds:cseg
- MyInt1c proc far
- push ds
- push ax
- push bx
- push dx
- mov ax, cseg
- mov ds, ax
-
- mov al, CurSw
- mov LastSw, al
-
- mov dx, 900h ;Read the 8 switches.
- mov ah, 84h
- int 15h
-
- mov CurSw, al
- xor al, LastSw ;See if any changes
- jz NoChanges
- and al, CurSw ;See if sw just went down.
- jz NoChanges
-
-
- ; If a switch has just gone down, output an appropriate set of scan codes
- ; for it, if that key is active. Note that pressing *any* key will reset
- ; all the other key indexes.
-
- test al, 1 ;See if Sw0 (trigger) was pulled.
- jz NoSw0
- cmp Sw0.Pgmd, 0
- je NoChanges
- mov ax, 0
- mov Left.Index, ax ;Reset the key indexes for all keys
- mov Right.Index, ax ; except SW0.
- mov Up.Index, ax
- mov Down.Index, ax
- mov Sw1.Index, ax
- mov Sw2.Index, ax
- mov Sw3.Index, ax
- mov bx, Sw0.Index
- mov ax, Sw0.Index
- mov bx, Sw0.Ptrs[bx]
- add ax, 2
- cmp ax, Sw0.Cnt
- jb SetSw0
- mov ax, 0
- SetSw0: mov Sw0.Index, ax
- call PutStrInBuf
- jmp NoChanges
-
-
-
- NoSw0: test al, 2 ;See if Sw1 (left sw) was pressed.
- jz NoSw1
- cmp Sw1.Pgmd, 0
- je NoChanges
- mov ax, 0
- mov Left.Index, ax ;Reset the key indexes for all keys
- mov Right.Index, ax ; except Sw1.
- mov Up.Index, ax
- mov Down.Index, ax
- mov Sw0.Index, ax
- mov Sw2.Index, ax
- mov Sw3.Index, ax
- mov bx, Sw1.Index
- mov ax, Sw1.Index
- mov bx, Sw1.Ptrs[bx]
- add ax, 2
- cmp ax, Sw1.Cnt
- jb SetSw1
- mov ax, 0
- SetSw1: mov Sw1.Index, ax
- call PutStrInBuf
- jmp NoChanges
-
-
- NoSw1: test al, 4 ;See if Sw2 (middle sw) was pressed.
- jz NoSw2
- cmp Sw2.Pgmd, 0
- je NoChanges
- mov ax, 0
- mov Left.Index, ax ;Reset the key indexes for all keys
- mov Right.Index, ax ; except Sw2.
- mov Up.Index, ax
- mov Down.Index, ax
- mov Sw0.Index, ax
- mov Sw1.Index, ax
- mov Sw3.Index, ax
- mov bx, Sw2.Index
- mov ax, Sw2.Index
- mov bx, Sw2.Ptrs[bx]
- add ax, 2
- cmp ax, Sw2.Cnt
- jb SetSw2
- mov ax, 0
- SetSw2: mov Sw2.Index, ax
- call PutStrInBuf
- jmp NoChanges
-
-
- NoSw2: test al, 8 ;See if Sw3 (right sw) was pressed.
- jz NoSw3
- cmp Sw3.Pgmd, 0
- je NoChanges
- mov ax, 0
- mov Left.Index, ax ;Reset the key indexes for all keys
- mov Right.Index, ax ; except Sw3.
- mov Up.Index, ax
- mov Down.Index, ax
- mov Sw0.Index, ax
- mov Sw1.Index, ax
- mov Sw2.Index, ax
- mov bx, Sw3.Index
- mov ax, Sw3.Index
- mov bx, Sw3.Ptrs[bx]
- add ax, 2
- cmp ax, Sw3.Cnt
- jb SetSw3
- mov ax, 0
- SetSw3: mov Sw3.Index, ax
- call PutStrInBuf
- jmp NoChanges
-
-
- NoSw3: test al, 10h ;See if Cooly was pressed upwards.
- jz NoUp
- cmp Up.Pgmd, 0
- je NoChanges
- mov ax, 0
- mov Right.Index, ax ;Reset all but Up.
- mov Left.Index, ax
- mov Down.Index, ax
- mov Sw0.Index, ax
- mov Sw1.Index, ax
- mov Sw2.Index, ax
- mov Sw3.Index, ax
- mov bx, Up.Index
- mov ax, Up.Index
- mov bx, Up.Ptrs[bx]
- add ax, 2
- cmp ax, Up.Cnt
- jb SetUp
- mov ax, 0
- SetUp: mov Up.Index, ax
- call PutStrInBuf
- jmp NoChanges
-
-
- NoUp: test al, 20h ;See if Cooly was pressed to the left.
- jz NoLeft
- cmp Left.Pgmd, 0
- je NoChanges
- mov ax, 0
- mov Right.Index, ax ;Reset all but Left.
- mov Up.Index, ax
- mov Down.Index, ax
- mov Sw0.Index, ax
- mov Sw1.Index, ax
- mov Sw2.Index, ax
- mov Sw3.Index, ax
- mov bx, Left.Index
- mov ax, Left.Index
- mov bx, Left.Ptrs[bx]
- add ax, 2
- cmp ax, Left.Cnt
- jb SetLeft
- mov ax, 0
- SetLeft: mov Left.Index, ax
- call PutStrInBuf
- jmp NoChanges
-
-
- NoLeft: test al, 40h ;See if Cooly was pressed to Right
- jz NoRight
- cmp Right.Pgmd, 0
- je NoChanges
- mov ax, 0
- mov Left.Index, ax ;Reset all but Right.
- mov Up.Index, ax
- mov Down.Index, ax
- mov Sw0.Index, ax
- mov Sw1.Index, ax
- mov Sw2.Index, ax
- mov Sw3.Index, ax
- mov bx, Right.Index
- mov ax, Right.Index
- mov bx, Right.Ptrs[bx]
- add ax, 2
- cmp ax, Right.Cnt
- jb SetRight
- mov ax, 0
- SetRight: mov Right.Index, ax
- call PutStrInBuf
- jmp NoChanges
-
-
- NoRight: test al, 80h ;See if Cooly was pressed Downward.
- jz NoChanges
- cmp Down.Pgmd, 0
- je NoChanges
- mov ax, 0
- mov Left.Index, ax ;Reset all but Down.
- mov Up.Index, ax
- mov Right.Index, ax
- mov Sw0.Index, ax
- mov Sw1.Index, ax
- mov Sw2.Index, ax
- mov Sw3.Index, ax
- mov bx, Down.Index
- mov ax, Down.Index
- mov bx, Down.Ptrs[bx]
- add ax, 2
- cmp ax, Down.Cnt
- jb SetDown
- mov ax, 0
- SetDown: mov Down.Index, ax
- call PutStrInBuf
-
- NoChanges: pop dx
- pop bx
- pop ax
- pop ds
- jmp cs:Int1CVect
- MyInt1c endp
- assume ds:nothing
-
- ; PutStrInBuf- BX points at a zero terminated string of words.
- ; Output each word by calling PutInBuffer.
-
- PutStrInBuf proc near
- push ax
- push bx
- PutLoop: mov ax, [bx]
- test ax, ax
- jz PutDone
- call PutInBuffer
- add bx, 2
- jmp PutLoop
-
- PutDone: pop bx
- pop ax
- ret
- PutStrInBuf endp
-
- ; PutInBuffer- Outputs character and scan code in AX to the type ahead
- ; buffer.
-
- assume ds:nothing
- KbdHead equ word ptr ds:[1ah]
- KbdTail equ word ptr ds:[1ch]
- KbdBuffer equ word ptr ds:[1eh]
- EndKbd equ 3eh
- Buffer equ 1eh
-
- PutInBuffer proc near
- push ds
- push bx
- mov bx, 40h
- mov ds, bx
- pushf
- cli ;This is a critical region!
- mov bx, KbdTail ;Get ptr to end of type
- inc bx ; ahead buffer and make room
- inc bx ; for this character.
- cmp bx, buffer+32 ;At physical end of buffer?
- jb NoWrap
- mov bx, buffer ;Wrap back to 1eH if at end.
- ;
- NoWrap: cmp bx, KbdHead ;Buffer overrun?
- je PIBDone
- xchg KbdTail, bx ;Set new, get old, ptrs.
- mov ds:[bx], ax ;Output AX to old location.
- PIBDone: popf ;Restore interrupts
- pop bx
- pop ds
- ret
- PutInBuffer endp
-
-
-
- ;****************************************************************************
- ;
- ; FindCode: On entry, ES:DI points at some code in *this* program which
- ; appears in the ATP game. DS:SI points at a block of memory
- ; in the ATP game. FindCode searches through memory to find the
- ; suspect piece of code and returns DS:SI pointing at the start of
- ; that code. This code assumes that it *will* find the code!
- ; It returns the carry clear if it finds it, set if it doesn't.
-
- FindCode proc near
- push ax
- push bx
- push dx
-
- DoCmp: mov dx, 1000h
- CmpLoop: push di ;Save ptr to compare code.
- push si ;Save ptr to start of string.
- push cx ;Save count.
- repe cmpsb
- pop cx
- pop si
- pop di
- je FoundCode
- inc si
- dec dx
- jne CmpLoop
- sub si, 1000h
- mov ax, ds
- inc ah
- mov ds, ax
- cmp ax, 9000h
- jb DoCmp
-
- pop dx
- pop bx
- pop ax
- stc
- ret
-
- FoundCode: pop dx
- pop bx
- pop ax
- clc
- ret
- FindCode endp
-
-
- ;****************************************************************************
- ;
- ; Joystick and button routines which appear in application code. This code is
- ; really data as the INT 21h patch code searches through memory for this code
- ; after loading a file from disk.
-
-
-
- JoyStickCode proc near
- sti
- neg bx
- neg di
- pop bp
- pop dx
- pop cx
- ret
- mov bp, bx
- in al, dx
- mov bl, al
- not al
- and al, ah
- jnz $+11h
- in al, dx
- JoyStickCode endp
- EndJSC:
-
- JoyLength = EndJSC-JoyStickCode
-
- ReadSwCode proc
- mov dx, 201h
- in al, dx
- xor al, 0ffh
- and ax, 0f0h
- ReadSwCode endp
- EndRSC:
-
- ButtonLength = EndRSC-ReadSwCode
-
- cseg ends
-
-
- Installation segment
-
- ; Move these things here so they do not consume too much space in the
- ; resident part of the patch.
-
- DfltFCB db 3," ",0,0,0,0,0
- CmdLine db 2, " ", 0dh, 126 dup (" ") ;Cmd line for program
- Pgm db "XWING.EXE",0
- db 128 dup (?) ;For user supplied name
-
-
- ; ChkBIOS15- Checks to see if the INT 15 driver for FSPro is present in memory.
-
- ChkBIOS15 proc far
- mov ah, 84h
- mov dx, 8100h
- int 15h
- mov di, bx
- strcmpl
- db "CH Products:Flightstick Pro",0
- jne NoDriverLoaded
- ret
-
- NoDriverLoaded: print
- byte "CH Products SGDI driver for Flightstick Pro is not "
- byte "loaded into memory.",cr,lf
- byte "Please run FSPSGDI before running this program."
- byte cr,lf,0
- exitpgm
-
- ChkBIOS15 endp
-
-
- ;****************************************************************************
- ;
- ; Identify- Prints a sign-on message.
-
- assume ds:nothing
- Identify proc far
-
- ; Print a welcome string. Note that the string "VersionStr" will be
- ; modified by the "version.exe" program each time you assemble this code.
-
- print
- db cr,lf,lf
- byte "╓───────────────────────────────────────╖",cr,lf
- byte "║ X W I N G P A T C H ║",cr,lf
- byte "║ CH Products Flightstick Pro ║",cr,lf
- byte "║ Copyright 1993, 1994, Randall Hyde ║",cr,lf
- byte "╙───────────────────────────────────────╜",cr,lf
- db lf
- db 0
-
- ret
- Identify endp
-
- ;****************************************************************************
- ;
- ; Calibrate the throttle down here:
-
- assume ds:nothing
- Calibrate proc far
- print
- byte cr,lf,lf
- byte "Calibration:",cr,lf,lf
- byte "Move the throttle to one extreme and press any "
- byte "button:",0
-
- call Wait4Button
- mov ah, 84h
- mov dx, 1h
- int 15h
- push dx ;Save pot 3 reading.
-
- print
- byte cr,lf
- byte "Move the throttle to the other extreme and press "
- byte "any button:",0
-
- call Wait4Button
- mov ah, 84h
- mov dx, 1
- int 15h
- pop bx
- mov ax, dx
- cmp ax, bx
- jb RangeOkay
- xchg ax, bx
- RangeOkay: mov cx, bx ;Compute a centered value.
- sub cx, ax
- shr cx, 1
- add cx, ax
- mov ah, 84h
- mov dx, 303h ;Calibrate pot three.
- int 15h
- ret
- Calibrate endp
-
-
-
- Wait4Button proc near
- mov ah, 84h ;First, wait for all buttons
- mov dx, 0 ; to be released.
- int 15h
- and al, 0F0h
- cmp al, 0F0h
- jne Wait4Button
-
- mov cx, 0
- Delay: loop Delay
-
- Wait4Press: mov ah, 1 ;Eat any characters from the
- int 16h ; keyboard which come along, and
- je NoKbd ; handle ctrl-C as appropriate.
- getc
-
- NoKbd: mov ah, 84h ;Now wait for any button to be
- mov dx, 0 ; pressed.
- int 15h
- and al, 0F0h
- cmp al, 0F0h
- je Wait4Press
-
- ret
- Wait4Button endp
-
-
-
- Installation ends
-
- sseg segment para stack 'STACK'
- dw 256 dup (0)
- endstk dw ?
- sseg ends
-
- zzzzzzseg segment para public 'zzzzzzseg'
- Heap db 1024 dup (0)
- zzzzzzseg ends
-
- end Main
-